package m

import (
	"GameServer/Game/cache"
	"GameServer/Game/dbmodule"
	"GameServer/Game/errors"

	"github.com/globalsign/mgo/bson"
	log "github.com/sirupsen/logrus"
)

// 用户成就
type UserAchiev struct {
	BaseM
	Uid         bson.ObjectId         `bson:"_id" json:"_id"`                 // 用户uid
	AchievInfos map[int64]*AchievInfo `bson:"achievInfos" json:"achievInfos"` // 成就列表，为成就类型
}

// 成就信息
type AchievInfo struct {
	AchievType int64     `bson:"achievType" json:"achievType"` // 成就类型
	Progress   int64     `bson:"progress" json:"progress"`     // 成就进度
	AchievLst  []*Achiev `bson:"achievLst" json:"achievLst"`   // 成就列表
}

// 成就状态
type Achiev struct {
	Tid      int64 `bson:"tid" json:"tid"`           // 成就tid
	State    int64 `bson:"state" json:"state"`       // 成就状态 0.未激活，1.激活，未领取，2.已领取
	Progress int64 `bson:"progress" json:"progress"` // 成就进度阈值
}

// 累计成就奖励
type AchievTotal struct {
	BaseM
	Uid        bson.ObjectId `bson:"_id" json:"_id"`               // 用户uid
	Tid        int64         `bson:"tid" json:"tid"`               // 第几轮
	StarCur    int64         `bson:"starCur" json:"starCur"`       // 当前星星
	StarAchiev int64         `bson:"starAchiev" json:"starAchiev"` // 成就星星总数
}

// 成就辅助信息
type AchievAuxiliary struct {
	BaseM
	Uid bson.ObjectId `bson:"_id" json:"_id"` // 用户uid
	// 记录不消耗体力连续打开的格子数，如果使用体力，这个重置零。
	ContinuityOpenGrid int64 `bson:"continuityOpenGrid" json:"continuityOpenGrid"`
	// 一天内消耗体力
	OneDayTime   int64   `bson:"oneDayTime" json:"oneDayTime"`     // 记录当天起始时间，xxxx-xx-xx 00:00:00
	OneDayEnergy int64   `bson:"oneDayEnergy" json:"oneDayEnergy"` // 记录累计一天的体力
	AchievChange []int64 `bson:"achievChange" json:"achievChange"` // 记录到达状态的成就，保存成就的tid
}

// 玩家成就：创建
func NewUserAchiev() cache.EntryI {
	return &UserAchiev{
		AchievInfos: make(map[int64]*AchievInfo),
	}
}

// 玩家成就：保存信息
func (ua *UserAchiev) Save() (err error) {
	err = dbmodule.MgoDB.GameDB.Upsert("UserAchiev", bson.M{"_id": ua.Uid}, ua)
	return
}

// 玩家成就：加载
func (ua *UserAchiev) Load(key interface{}) (err error) {
	switch key.(type) {
	case string:
		if key.(string) == "" {
			return errors.New("无效的key load, key empty")
		}
		ua.Uid = bson.ObjectIdHex(key.(string))
	case bson.ObjectId:
		ua.Uid = key.(bson.ObjectId)
	default:
		log.WithFields(log.Fields{
			"method": "UserAchiev_Load",
			"data":   key,
		}).Error("无效的key load")
		return errors.New("无效的key load")
	}
	return ua.LoadData()
}

// 玩家成就：加载数据
func (ua *UserAchiev) LoadData() (err error) {
	err = dbmodule.MgoDB.GameDB.FindOne("UserAchiev", bson.M{"_id": ua.Uid}, nil, &ua)
	if err != nil {
		if err.Error() == "not found" {
			return nil
		}
		return
	}
	if ua.AchievInfos == nil {
		ua.AchievInfos = make(map[int64]*AchievInfo)
	}
	return
}

// 玩家成就：更新数据
func (ua *UserAchiev) Update(val *UserAchiev) {
	Cache.Put("UserAchiev", val.Uid.Hex(), val)
	val.UpdateData()
}

// 获取成就列表
func (u *User) GetUserAchiev(uid string) (r *UserAchiev, ok bool) {
	v, ok := Cache.Get("UserAchiev", uid)
	r = v.(*UserAchiev)
	return
}

// 累计成就奖励：创建
func NewAchievTotal() cache.EntryI {
	return &AchievTotal{}
}

// 累计成就奖励：保存信息
func (at *AchievTotal) Save() (err error) {
	err = dbmodule.MgoDB.GameDB.Upsert("AchievTotal", bson.M{"_id": at.Uid}, at)
	return
}

// 累计成就奖励：加载
func (at *AchievTotal) Load(key interface{}) (err error) {
	switch key.(type) {
	case string:
		if key.(string) == "" {
			return errors.New("无效的key load, key empty")
		}
		at.Uid = bson.ObjectIdHex(key.(string))
	case bson.ObjectId:
		at.Uid = key.(bson.ObjectId)
	default:
		log.WithFields(log.Fields{
			"method": "AchievTotal_Load",
			"data":   key,
		}).Error("无效的key load")
		return errors.New("无效的key load")
	}
	return at.LoadData()
}

// 累计成就奖励：加载数据
func (at *AchievTotal) LoadData() (err error) {
	err = dbmodule.MgoDB.GameDB.FindOne("AchievTotal", bson.M{"_id": at.Uid}, nil, &at)
	if err != nil {
		if err.Error() == "not found" {
			return nil
		}
		return
	}
	return
}

// 累计成就奖励：更新数据
func (at *AchievTotal) Update(val *AchievTotal) {
	Cache.Put("AchievTotal", val.Uid.Hex(), val)
	val.UpdateData()
}

// 获取成就累计信息
func (u *User) GetAchievTotal(uid string) (r *AchievTotal, ok bool) {
	v, ok := Cache.Get("AchievTotal", uid)
	r = v.(*AchievTotal)
	return
}

// 成就辅助信息：创建
func NewAchievAuxiliary() cache.EntryI {
	return &AchievAuxiliary{}
}

// 成就辅助信息：保存信息
func (aa *AchievAuxiliary) Save() (err error) {
	err = dbmodule.MgoDB.GameDB.Upsert("AchievAuxiliary", bson.M{"_id": aa.Uid}, aa)
	return
}

// 成就辅助信息：加载
func (aa *AchievAuxiliary) Load(key interface{}) (err error) {
	switch key.(type) {
	case string:
		if key.(string) == "" {
			return errors.New("无效的key load, key empty")
		}
		aa.Uid = bson.ObjectIdHex(key.(string))
	case bson.ObjectId:
		aa.Uid = key.(bson.ObjectId)
	default:
		log.WithFields(log.Fields{
			"method": "AchievAuxiliary_Load",
			"data":   key,
		}).Error("无效的key load")
		return errors.New("无效的key load")
	}
	return aa.LoadData()
}

// 成就辅助信息：加载数据
func (aa *AchievAuxiliary) LoadData() (err error) {
	err = dbmodule.MgoDB.GameDB.FindOne("AchievAuxiliary", bson.M{"_id": aa.Uid}, nil, &aa)
	if err != nil {
		if err.Error() == "not found" {
			return nil
		}
		return
	}
	if aa.AchievChange == nil {
		aa.AchievChange = make([]int64, 0)
	}
	return
}

// 成就辅助信息：更新数据
func (aa *AchievAuxiliary) Update(val *AchievAuxiliary) {
	Cache.Put("AchievAuxiliary", val.Uid.Hex(), val)
	val.UpdateData()
}

// 获取成就辅助信息
func (u *User) GetAchievAuxiliary(uid string) (r *AchievAuxiliary, ok bool) {
	v, ok := Cache.Get("AchievAuxiliary", uid)
	r = v.(*AchievAuxiliary)
	return
}
